package com.szgz.platform.service;

import com.github.dockerjava.api.DockerClient;
import com.github.dockerjava.api.command.CreateContainerResponse;
import com.github.dockerjava.api.model.Bind;
import com.github.dockerjava.api.model.HostConfig;
import com.github.dockerjava.api.model.Volume;
import com.github.dockerjava.core.DockerClientBuilder;
import org.springframework.stereotype.Service;

import java.io.*;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.UUID;

@Service
public class CodeRunService {

    public String runCode(String code, String language) {
        if (!"python".equalsIgnoreCase(language)) {
            return "暂不支持该语言";
        }

        String result;
        DockerClient dockerClient = DockerClientBuilder.getInstance().build();
        String tempDir = System.getProperty("java.io.tmpdir") + File.separator + UUID.randomUUID();
        File dir = new File(tempDir);
        dir.mkdirs();

        try {
            File codeFile = new File(dir, "main.py");
            try (FileWriter writer = new FileWriter(codeFile)) {
                writer.write(code);
            }

            Volume volume = new Volume("/code");
            HostConfig hostConfig = HostConfig.newHostConfig()
                    .withBinds(new Bind(dir.getAbsolutePath(), volume));

            CreateContainerResponse container = dockerClient.createContainerCmd("python:3.8")
                    .withCmd("python", "/code/main.py")
                    .withHostConfig(hostConfig)
                    .exec();

            String containerId = container.getId();
            dockerClient.startContainerCmd(containerId).exec();

            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
            dockerClient.logContainerCmd(containerId)
                    .withStdOut(true)
                    .withStdErr(true)
                    .exec(new com.github.dockerjava.core.command.LogContainerResultCallback() {
                        @Override
                        public void onNext(com.github.dockerjava.api.model.Frame frame) {
                            try {
                                outputStream.write(frame.getPayload());
                            } catch (IOException e) {
                                e.printStackTrace();
                            }
                        }
                    }).awaitCompletion();

            result = outputStream.toString();
            dockerClient.removeContainerCmd(containerId).withForce(true).exec();
        } catch (Exception e) {
            result = "运行出错: " + e.getMessage();
        } finally {
            try {
                Files.walk(dir.toPath())
                        .map(Path::toFile)
                        .sorted((o1, o2) -> -o1.compareTo(o2))
                        .forEach(File::delete);
            } catch (Exception ignore) {}
        }
        return result;
    }
}